package com.glgc.projecti.common;
import net.sf.json.JSONObject;

import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class WeixinUtils {
	
	public static void main(String[] args) throws BizException {
		String access_token = getAccessToken();
//		getTicket(access_token);
	}
	

	private final static Logger logger = LoggerFactory.getLogger(WeixinUtils.class);
    public static Map<String, String> wish(HttpServletRequest request) throws BizException {
    	String openId = (String) request.getSession().getAttribute(CommonConstant.WEIXING_OPEN_ID);
    	Map<String, String> ret = null;
    	if (!CommonUtils.isNotEmpty(openId)) {				 
			return ret;
		}
        String ticket = (String) request.getSession().getServletContext().getAttribute("ticket");
        Date updateTime = (Date) request.getSession().getServletContext().getAttribute("ticket_update_time");

        if (ticket != null && updateTime != null && new Date().getTime() - updateTime.getTime() < 7000000) {
        	logger.debug("不需要重新查询Ticket！上次查找时间是：" + updateTime);
        } else {
        	logger.debug("重新查询Ticket。");
            String accessToken = getAccessToken();
            ticket = getTicket(accessToken);            
            
            request.getSession().getServletContext().setAttribute("ticket", ticket);
            request.getSession().getServletContext().setAttribute("ticket_update_time", new Date());
        }

        logger.debug("====================.");
        String host_ip = ResourceBundle.getBundle("config").getString("HOST_WWW");
        // 注意 URL 一定要动态获取，不能 hardcode
        String url = host_ip + request.getRequestURI().toString() 
        		+ (request.getQueryString() == null ? "" : ("?" + request.getQueryString()));
        logger.info("URL: " + url);
        ret = sign(ticket, url);
        for (Map.Entry<String, String> entry : ret.entrySet()) {
            logger.info(entry.getKey() + ": " + entry.getValue());
        }

        ret.put("basePath", request.getRequestURL().toString());
        ret.put("appID", ResourceBundle.getBundle("config").getString("app_wx_id"));

        return ret;
    }

	private static String getTicket(String accessToken) throws BizException {
		String ticket;
		String token_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
		token_url = token_url.replace("ACCESS_TOKEN", accessToken);
		String response = HttpRequestTool.httpRequest(token_url, "GET", "");
		//获取ticket
		JSONObject resMap = new JSONObject();
		ObjectMapper om = new ObjectMapper();
		if (response != null) {
			try {
				resMap = om.readValue(response.getBytes("UTF-8"), JSONObject.class);
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
		
		ticket = resMap.getString("ticket");
		logger.debug("ticket: [" + ticket + "]");
		return ticket;
	}
	 

    private static String getAccessToken() throws BizException {
//    	String appID = "wxa7c502b7dce34bb0";
    	String appID = ResourceBundle.getBundle("config").getString("app_wx_id");
//    	String appsecret = "35e4fbf54a5c7367298d87bdcb5f1b5b";
    	String appsecret = ResourceBundle.getBundle("config").getString("app_wx_secret");
    	String format = ResourceBundle.getBundle("config").getString("weixin_access_token_url");
		String httpsRequest = HttpRequestTool.httpRequest(format, "GET", null);
		System.out.println(httpsRequest);
		JSONObject resMap = new JSONObject();
		ObjectMapper om = new ObjectMapper();
		if (httpsRequest != null) {
			try {
				resMap = om.readValue(httpsRequest.getBytes("UTF-8"), JSONObject.class);
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
		String access_token = resMap.getString("accessToken");
		logger.debug("access_token: [" + access_token + "]");
		return access_token;
	}

	public static Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写，且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + nonce_str +
                "&timestamp=" + timestamp +
                "&url=" + url;
        logger.debug(string1);

        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        ret.put("url", url);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);

        return ret;
    }


    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}
